package com.elegant.code.spi.web.gateway.plugins.auth;

import com.elegant.code.spi.web.auth.AuthConstant;
import com.elegant.code.spi.web.auth.Authorize;
import com.elegant.code.spi.web.gateway.PluginChain;
import com.elegant.code.spi.web.gateway.plugins.Plugin;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.WebRequestInterceptor;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import org.springframework.web.servlet.handler.WebRequestHandlerInterceptorAdapter;
import reactor.core.publisher.Mono;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;

public class AuthorizePlugin implements Plugin {


    @Override
    public HandlerInterceptor getInterceptor() {
        return new HandlerInterceptor(){
            @Override
            public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
                if (!(handler instanceof HandlerMethod)) {
                    return true;
                }
                HandlerMethod handlerMethod = (HandlerMethod) handler;

                Authorize authorize = handlerMethod.getMethod().getAnnotation(Authorize.class);
                if (authorize == null) {
                    return true; // no need to authorize
                }

                String[] allowedHeaders = authorize.value();
                String authzHeader = request.getHeader(AuthConstant.AUTHORIZATION_HEADER);

                if (StringUtils.isEmpty(authzHeader)) {
                    throw new RuntimeException(AuthConstant.ERROR_MSG_MISSING_AUTH_HEADER);
                }

                if (!Arrays.asList(allowedHeaders).contains(authzHeader)) {
                    throw new RuntimeException(AuthConstant.ERROR_MSG_DO_NOT_HAVE_ACCESS);
                }
                return true;
            }
        };
    }

    @Override
    public int getOrder() {
        return 0;
    }

    @Override
    public String named() {
        return null;
    }

    @Override
    public Boolean skip(ServerWebExchange exchange) {
        return false;
    }
}
